{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 1 将图像，带噪音图像，以及噪音图像通过Sobel算子、Scharr算子、Laplacian算子和Canny算子处理后的图像整合到一张图上比较。",
   "id": "2312f9efd4eb5fe5"
  },
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "is_executing": true
    }
   },
   "source": [
    "import cv2 as cv\n",
    "import numpy as np\n",
    "\n",
    "# 读取图像\n",
    "image = cv.imread('./mm.png')\n",
    "\n",
    "# 添加高斯噪音创建带噪音图像\n",
    "noise = np.random.normal(0, 25, image.shape).astype(np.uint8)\n",
    "noisy_image = cv.add(image, noise)\n",
    "\n",
    "# 计算噪音图像（原始图像与带噪音图像的差异）\n",
    "noise_only = cv.subtract(noisy_image, image)\n",
    "\n",
    "# 共享的参数\n",
    "shared_params = {\n",
    "    \"org\": (10, 30),\n",
    "    \"fontFace\": cv.FONT_HERSHEY_SIMPLEX,\n",
    "    \"fontScale\": 1,\n",
    "    \"thickness\": 2,\n",
    "    \"color\": (0, 255, 0),\n",
    "    \"lineType\": cv.LINE_AA,\n",
    "}\n",
    "\n",
    "# 为所有图像添加文字标签\n",
    "def add_text(img, text):\n",
    "    return cv.putText(img.copy(), text, **shared_params)\n",
    "\n",
    "# 处理原始图像\n",
    "original_labeled = add_text(image, \"Original Image\")\n",
    "noisy_labeled = add_text(noisy_image, \"Noisy Image\")\n",
    "noise_only_labeled = add_text(noise_only, \"Noise Only\")\n",
    "\n",
    "# Sobel算子处理\n",
    "sobel_x_original = cv.Sobel(image, cv.CV_64F, 1, 0, ksize=3)\n",
    "sobel_y_original = cv.Sobel(image, cv.CV_64F, 0, 1, ksize=3)\n",
    "sobel_original = cv.convertScaleAbs(cv.magnitude(sobel_x_original, sobel_y_original))\n",
    "\n",
    "sobel_x_noisy = cv.Sobel(noisy_image, cv.CV_64F, 1, 0, ksize=3)\n",
    "sobel_y_noisy = cv.Sobel(noisy_image, cv.CV_64F, 0, 1, ksize=3)\n",
    "sobel_noisy = cv.convertScaleAbs(cv.magnitude(sobel_x_noisy, sobel_y_noisy))\n",
    "\n",
    "sobel_x_noise = cv.Sobel(noise_only, cv.CV_64F, 1, 0, ksize=3)\n",
    "sobel_y_noise = cv.Sobel(noise_only, cv.CV_64F, 0, 1, ksize=3)\n",
    "sobel_noise = cv.convertScaleAbs(cv.magnitude(sobel_x_noise, sobel_y_noise))\n",
    "\n",
    "sobel_original_labeled = add_text(sobel_original, \"Sobel - Original\")\n",
    "sobel_noisy_labeled = add_text(sobel_noisy, \"Sobel - Noisy\")\n",
    "sobel_noise_labeled = add_text(sobel_noise, \"Sobel - Noise\")\n",
    "\n",
    "# Scharr算子处理\n",
    "scharr_x_original = cv.Scharr(image, cv.CV_64F, 1, 0)\n",
    "scharr_y_original = cv.Scharr(image, cv.CV_64F, 0, 1)\n",
    "scharr_original = cv.convertScaleAbs(cv.magnitude(scharr_x_original, scharr_y_original))\n",
    "\n",
    "scharr_x_noisy = cv.Scharr(noisy_image, cv.CV_64F, 1, 0)\n",
    "scharr_y_noisy = cv.Scharr(noisy_image, cv.CV_64F, 0, 1)\n",
    "scharr_noisy = cv.convertScaleAbs(cv.magnitude(scharr_x_noisy, scharr_y_noisy))\n",
    "\n",
    "scharr_x_noise = cv.Scharr(noise_only, cv.CV_64F, 1, 0)\n",
    "scharr_y_noise = cv.Scharr(noise_only, cv.CV_64F, 0, 1)\n",
    "scharr_noise = cv.convertScaleAbs(cv.magnitude(scharr_x_noise, scharr_y_noise))\n",
    "\n",
    "scharr_original_labeled = add_text(scharr_original, \"Scharr - Original\")\n",
    "scharr_noisy_labeled = add_text(scharr_noisy, \"Scharr - Noisy\")\n",
    "scharr_noise_labeled = add_text(scharr_noise, \"Scharr - Noise\")\n",
    "\n",
    "# Laplacian算子处理\n",
    "laplacian_original = cv.convertScaleAbs(cv.Laplacian(image, cv.CV_64F))\n",
    "laplacian_noisy = cv.convertScaleAbs(cv.Laplacian(noisy_image, cv.CV_64F))\n",
    "laplacian_noise = cv.convertScaleAbs(cv.Laplacian(noise_only, cv.CV_64F))\n",
    "\n",
    "laplacian_original_labeled = add_text(laplacian_original, \"Laplacian - Original\")\n",
    "laplacian_noisy_labeled = add_text(laplacian_noisy, \"Laplacian - Noisy\")\n",
    "laplacian_noise_labeled = add_text(laplacian_noise, \"Laplacian - Noise\")\n",
    "\n",
    "# Canny算子处理\n",
    "canny_original = cv.Canny(image, 100, 200)\n",
    "canny_noisy = cv.Canny(noisy_image, 100, 200)\n",
    "canny_noise = cv.Canny(noise_only, 100, 200)\n",
    "\n",
    "# 将Canny二值图像转换为3通道以便显示\n",
    "canny_original_color = cv.cvtColor(canny_original, cv.COLOR_GRAY2BGR)\n",
    "canny_noisy_color = cv.cvtColor(canny_noisy, cv.COLOR_GRAY2BGR)\n",
    "canny_noise_color = cv.cvtColor(canny_noise, cv.COLOR_GRAY2BGR)\n",
    "\n",
    "canny_original_labeled = add_text(canny_original_color, \"Canny - Original\")\n",
    "canny_noisy_labeled = add_text(canny_noisy_color, \"Canny - Noisy\")\n",
    "canny_noise_labeled = add_text(canny_noise_color, \"Canny - Noise\")\n",
    "\n",
    "# 创建三行图像\n",
    "row1 = cv.hconcat([original_labeled, noisy_labeled, noise_only_labeled])\n",
    "row2 = cv.hconcat([sobel_original_labeled, sobel_noisy_labeled, sobel_noise_labeled])\n",
    "row3 = cv.hconcat([scharr_original_labeled, scharr_noisy_labeled, scharr_noise_labeled])\n",
    "row4 = cv.hconcat([laplacian_original_labeled, laplacian_noisy_labeled, laplacian_noise_labeled])\n",
    "row5 = cv.hconcat([canny_original_labeled, canny_noisy_labeled, canny_noise_labeled])\n",
    "\n",
    "\n",
    "# 垂直拼接所有行\n",
    "comparison_image = cv.vconcat([row1, row2, row3, row4, row5])\n",
    "height, width = comparison_image.shape[:2]\n",
    "if height > 1200 or width > 1800:\n",
    "    scale = min(1200/height, 1800/width)\n",
    "    new_width = int(width * scale)\n",
    "    new_height = int(height * scale)\n",
    "    comparison_image = cv.resize(comparison_image, (new_width, new_height))\n",
    "\n",
    "# 显示合并后的图像\n",
    "cv.imshow(\"Edge Detection Comparison\", comparison_image)\n",
    "cv.waitKey(0)\n",
    "cv.destroyAllWindows()\n"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 2.将图像及经过腐蚀，膨胀，开运算、闭运算，礼帽运算，黑帽运算，粗化、细化运算后的图像整合到一张图上做比较。",
   "id": "f0f7516586533862"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-29T12:37:52.527681Z",
     "start_time": "2025-10-29T12:37:47.261338Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import cv2 as cv\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "image = cv.imread(\"./ecllipse.png\")\n",
    "\n",
    "# 创建核\n",
    "kernel = np.ones((5,5), np.uint8)\n",
    "\n",
    "\n",
    "eroded_image = cv.erode(image, kernel, iterations=1)\n",
    "dilated_image = cv.dilate(image, kernel, iterations=1)\n",
    "\n",
    "# 水平拼接三个彩色图像\n",
    "combined = np.hstack((image, eroded_image, dilated_image))\n",
    "\n",
    "# 显示结果\n",
    "cv.imshow('Color Comparison: Original | Eroded | Dilated', combined)\n",
    "cv.waitKey(0)\n",
    "cv.destroyAllWindows()"
   ],
   "id": "4cb54b81a5633954",
   "outputs": [],
   "execution_count": 15
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "91af50eac1618571"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
